// all these methods were inside the contract-middleware
// now move all of them here to keep the middleware clean
import { trim } from 'lodash'
import { SHOW_CONTRACT_DESC_PARAM } from 'jsonql-constants'
import {
  isObjectHasKey,
  getDebug,
  handleOutput,
  packResult,
  ctxErrorHandler
} from '../utils'
const debug = getDebug('contracts:helpers')
/**
 * remove the description field
 * @param {boolean} showDesc true to keep
 * @param {object} contract json
 * @return {object} clean contract
 */
export const removeDesc = (showDesc, contract) => {
  debug('showDesc', showDesc)
  if (showDesc) {
    return contract;
  }
  let c = contract;
  for (let type in c) {
    for (let fn in c[type]) {
      if (isObjectHasKey(c[type][fn], 'description')) {
        delete c[type][fn].description;
        if (c[type][fn].returns && isObjectHasKey(c[type][fn].returns, 'description')) {
          delete c[type][fn].returns.description;
        }
      }
    }
  }
  return c;
}

/**
 * get the contract data @TODO might require some sort of security here
 * @param {object} opts options
 * @param {object} ctx koa
 * @return {undefined}
 */
export const handleContract = (opts, ctx, contract) => {
  // @1.3.2 add a filter here to exclude the description field
  // just to reduce the size, but we serve it up if this is request with
  // desc=1 param - useful for the jsonql-web-console
  // debug('handleContract', ctx.query.desc)
  const key = Object.keys(SHOW_CONTRACT_DESC_PARAM)[0]
  let desc = !!(ctx.query[key] && ctx.query[key] === SHOW_CONTRACT_DESC_PARAM[key])
  handleOutput(opts)(ctx, packResult(
    removeDesc(desc, contract)
  ))
}

/**
 * Search for the value from the CONTRACT_KEY_NAME
 * @param {object} ctx koa context
 * @param {string} contractKeyName the key to search
 * @return {string} the value from header
 */
export const searchContractAuth = function(ctx, contractKeyName) {
  // debug(`Try to get ${contractKeyName} from header`, ctx.request.header);
  return ctx.request.get(contractKeyName)
}

/**
 * Handle contract authorisation using a key
 * @param {object} ctx koa
 * @param {object} opts options
 * @return {boolean} true ok
 */
export const contractAuth = function(ctx, opts) {
  if (opts.contractKey !== false && opts.contractKeyName !== false) {
    const { contractKey, contractKeyName } = opts;
    // debug('Received this for auth', contractKeyName, contractKey);
    // @2019-05-08 we change from url query to header
    // const keyValueFromClient = trim(ctx.query[contractKeyName]);
    // debug('the query value', ctx.query);
    const keyValueFromClient = searchContractAuth(ctx, contractKeyName)

    switch (true) {
      case typeof contractKey === 'string':
          // debug('compare this two', keyValueFromClient, contractKey);
          return keyValueFromClient === contractKey;
        break;
      default:
        // @TODO what if we want to read the header?
        debug('Unsupported contract auth type method', typeof contractKey)
        return false;
    }
  }
  return true;
}
